package com.dao;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.ioc.DatabaseManagerFactory;
import com.util.Page;
import com.util.PageUtil;

import ejp.Database;
import ejp.DatabaseManager;
import ejp.Result;


/**
 * DAO的基本实现对象，需要子类继承
 * 
 * @author Administrator
 * 
 * @param <T>
 */
public abstract class BaseDAO<T> {
	/** 数据库管理对象 */
	private static final DatabaseManager dm = DatabaseManagerFactory.getDatabaseManager();
	/** 日志 */
	protected Logger logger = Logger.getLogger(this.getClass());

	/**
	 * 查询对象List
	 * 
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public List<T> queryObject(Class<T> cls) throws Exception {
		Database db = null;
		Result<T> results = null;
		List<T> list = new ArrayList<T>();
		try {
			db = dm.getDatabase();
			results = db.queryObject(cls);
			for (T t : results) {
				list.add(t);
			}
			return list;
		} catch (Exception e) {
			throw new Exception("查询对象异常", e);
		} finally {
			this.close(results, db);
		}
	}

	/**
	 * 查询对象总数量
	 * 
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public int queryCountNumByObject(Class<T> cls) throws Exception {
		Database db = null;
		Result<T> results = null;
		int count = 0;
		ResultSet rs = null;
		try {
			db = dm.getDatabase();
			results = db.queryObject(cls);
			rs = results.getResultSet();
			if(rs.next()){
				rs.last();
				count = rs.getRow();
			}
			return count;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("查询对象异常", e);
		} finally {
			if (rs != null) {
				rs.close();
			}
			this.close(results, db);
		}
	}

	/**
	 * 查询对象总数量
	 * 
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public Page queryObjectForPage(Class<T> cls, Page page) throws Exception {
		int total = 0;
		int tnum = 0;
		try {
			total = queryCountNumByObject(cls);
			tnum = (page.getCurrentPage() - 1) * page.everyPage;
			String sql = "limit " + tnum + "," + page.everyPage;
			List list = queryObject(cls, sql);
			page = PageUtil.createPage(page, total);
			page.setList(list);
			return page;
		} catch (Exception e) {
			throw new Exception("查询对象异常", e);
		}
	}

	/**
	 * 查询对象list
	 * 
	 * @param cls
	 * @param condition
	 * @param parameters
	 * @return
	 * @throws Exception
	 */
	public List<T> queryObject(Class<T> cls, String condition, Object... parameters) throws Exception {
		Database db = null;
		Result<T> results = null;
		List<T> list = new ArrayList<T>();
		try {
			db = dm.getDatabase();
			if (parameters == null)
				results = db.queryObject(cls, condition);
			else
				results = db.queryObject(cls, condition, parameters);
			for (T t : results) {
				list.add(t);
			}
			return list;
		} catch (Exception e) {
			throw new Exception("查询对象异常", e);
		} finally {
			this.close(results, db);
		}
	}

	/**
	 * 查询对象总数量
	 * 
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public int queryCountNumByObject(Class<T> cls, String condition, Object... parameters) throws Exception {
		Database db = null;
		Result<T> results = null;
		int total = 0;
		ResultSet rs = null;
		try {
			db = dm.getDatabase();
			if (parameters == null)
				results = db.queryObject(cls, condition);
			else
				results = db.queryObject(cls, condition, parameters);
			rs = results.getResultSet();
			if(rs.next()){
				rs.last();
				total = rs.getRow();
			}
			return total;
		} catch (Exception e) {
			throw new Exception("查询对象异常", e);
		} finally {
			if (rs != null) {
				rs.close();
			}
			this.close(results, db);
		}
	}

	/**
	 * 查询对象总数量
	 * 
	 * @param cls
	 * @return
	 * @throws Exception
	 */
	public Page queryObjectForPage(Class<T> cls, Page page, String condition, Object... parameters) throws Exception {
		int total = 0;
		int tnum = 0;
		tnum = page.getCurrentPage() * page.everyPage;
		try {
			total = queryCountNumByObject(cls, condition, parameters);
			List list = queryObject(cls, condition, parameters, "limit " + tnum + " " + page.everyPage);
			page = PageUtil.createPage(page, total);
			page.setList(list);
			return page;
		} catch (Exception e) {
			throw new Exception("查询对象异常", e);
		}
	}

	/**
	 * 查询对象
	 * 
	 * @param object
	 * @return
	 * @throws Exception
	 */
	public T queryByObjectId(Class<T> cls, String condition, Object... parameters) throws Exception {
		Database db = null;
		Result<T> results = null;
		T t = null;
		try {
			db = dm.getDatabase();
			results = db.queryObject(cls, condition, parameters);
			for (T i : results) {
				t = i;
				break;
			}
			return t;
		} catch (Exception e) {
			throw new Exception("查询对象异常", e);
		} finally {
			this.close(results, db);
		}
	}

	/**
	 * 查询对象
	 * 
	 * @param object
	 * @return
	 * @throws Exception
	 */
	public T queryObject(T object) throws Exception {
		Database db = null;
		Result<T> results = null;
		T t = null;
		try {
			db = dm.getDatabase();
			results = db.queryObject(object);
			for (T i : results) {
				t = i;
				break;
			}
			return t;
		} catch (Exception e) {
			throw new Exception("查询对象异常", e);
		} finally {
			this.close(results, db);
		}
	}

	/**
	 * 删除对象
	 * 
	 * @param obj
	 * @param externalClauses
	 * @param externalClausesParameters
	 * @return
	 */
	public boolean deleteObject(Object obj, String externalClauses, Object... externalClausesParameters) {
		Database db = null;
		try {
			db = dm.getDatabase();
			db.beginTransaction();
			db.deleteObject(obj, externalClauses, externalClausesParameters);
			return true;
		} catch (Exception e) {
			try {
				if (db != null)
					db.rollback();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("删除对象异常", e);
			return false;
		} finally {
			try {
				db.endTransaction();
				this.close(null, db);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 删除对象
	 * 
	 * @param obj
	 * @return
	 */
	public boolean deleteObject(Object obj) {
		Database db = null;
		try {
			db = dm.getDatabase();
			db.beginTransaction();
			db.deleteObject(obj);
			return true;
		} catch (Exception e) {
			try {
				if (db != null)
					db.rollback();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("删除对象异常", e);
			return false;
		} finally {
			try {
				db.endTransaction();
				this.close(null, db);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 更新对象
	 * 
	 * @param sql
	 * @return
	 */
	public boolean executeUpdate(String sql) {
		Database db = null;
		try {
			db = dm.getDatabase();
			db.beginTransaction();
			db.executeUpdate(sql);
			return true;
		} catch (Exception e) {
			try {
				if (db != null)
					db.rollback();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("SQL更新产生异常", e);
			return false;
		} finally {
			try {
				db.endTransaction();
				this.close(null, db);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 保存对象
	 * 
	 * @param obj
	 * @param externalClauses
	 * @param externalClausesParameters
	 * @return
	 */
	public boolean saveObject(Object obj, String externalClauses, Object... externalClausesParameters) {
		Database db = null;
		try {
			db = dm.getDatabase();
			db.beginTransaction();
			db.saveObject(obj, externalClauses, externalClausesParameters);
			return true;
		} catch (Exception e) {
			try {
				if (db != null)
					db.rollback();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("对象更新产生异常", e);
			return false;
		} finally {
			try {
				db.endTransaction();
				this.close(null, db);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 保存对象
	 * 
	 * @param obj
	 * @return
	 */
	public boolean saveObject(Object obj) {
		Database db = null;
		try {
			db = dm.getDatabase();
			db.beginTransaction();
			db.saveObject(obj);
			return true;
		} catch (Exception e) {
			try {
				if (db != null)
					db.rollback();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("对象更新产生异常", e);
			return false;
		} finally {
			try {
				db.endTransaction();
				this.close(null, db);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 批量保存
	 * 
	 * @param objects
	 * @return
	 */
	public boolean saveObjectByBatch(List<Object> objects) {
		Database db = null;
		try {
			db = dm.getDatabase();
			db.beginTransaction();
			db.beginBatch();
			for (Object o : objects) {
				db.saveObject(o);
			}
			db.executeBatch();
			db.endBatch();
			return true;

		} catch (Exception e) {
			try {
				if (db != null)
					db.rollback();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("对象更新产生异常", e);
			return false;
		} finally {
			try {
				db.endTransaction();
				this.close(null, db);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 返回result
	 * 
	 * @param sql
	 * @return
	 */
	public List<T> findObjectBySql(Class<T> cls, String sql) {
		Database db = null;
		Result<T> results = null;
		List<T> list = new ArrayList<T>();
		try {
			db = dm.getDatabase();
			results = (Result<T>) db.executeQuery(sql).setClass(cls);
			for (T t : results) {
				list.add(t);
			}
		} catch (Exception e) {
			logger.error("对象更新产生异常", e);
		} finally {
			this.close(results, db);
		}
		return list;
	}

	/**
	 * 返回result
	 * 
	 * @param sql
	 * @return
	 */
	public int findObjectCountBySql(Class<T> cls, String sql) {
		Database db = null;
		Result<T> results = null;
		int count = 0;
		ResultSet rs = null;
		try {
			db = dm.getDatabase();
			results = (Result<T>) db.executeQuery(sql).setClass(cls);
			rs = results.getResultSet();
			if(rs.next()){
				rs.last();
				count = rs.getRow();
			}
		} catch (Exception e) {
			logger.error("对象更新产生异常", e);
		} finally {
			try {
				if (rs != null)
					rs.close();
				this.close(results, db);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error(e.getMessage());
			}
		}
		return count;
	}

	/**
	 * 取回分页Page对象
	 * 
	 * @param sql
	 * @param page
	 * @return page
	 * @throws Exception
	 */
	public Page findPageObjBySql(String sql, Page page, Class<T> cls) throws Exception {
		int beginrows = (page.getCurrentPage() - 1) * page.getEveryPage();
		int totalRecords = findObjectCountBySql(cls, sql);
		if (totalRecords > 0) {
			page = PageUtil.createPage(page, totalRecords);
			sql += "  limit " + beginrows + ", " + page.getEveryPage();
			List list = findObjectBySql(cls, sql);
			page.setList(list);
		}
		return page;
	}

	/**
	 * 更新
	 * 
	 * @param sql
	 * @return
	 */
	public boolean executeUpdateObjectBySql(String sql) {
		Database db = null;
		try {
			db = dm.getDatabase();
			db.beginTransaction();
			db.executeUpdate(sql);
			return true;
		} catch (Exception e) {
			try {
				if (db != null)
					db.rollback();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("对象更新产生异常", e);
			return false;
		} finally {
			try {
				db.endTransaction();
				this.close(null, db);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 更新对象
	 * 
	 * @param obj
	 * @param externalClauses
	 * @param externalClausesParameters
	 * @return
	 */
	public boolean updateObject(Object obj, String externalClauses, Object... externalClausesParameters) {
		Database db = null;
		try {
			db = dm.getDatabase();
			db.beginTransaction();
			db.saveObject(obj, externalClauses, externalClausesParameters);
			return true;
		} catch (Exception e) {
			try {
				if (db != null)
					db.rollback();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			logger.error("对象更新产生异常", e);
			return false;
		} finally {
			try {
				db.endTransaction();
				this.close(null, db);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 关闭连接
	 * 
	 * @param rs
	 * @param db
	 */
	private void close(Result<T> rs, Database db) {
		try {
			if (rs != null)
				rs.close();
			if (db != null)
				db.close();
		} catch (Exception e) {
			logger.error("关闭连接产生异常", e);
		}
	}
}
